package com.huangmingfu;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: 黄名富
 * @Description: 组合模式
 */
public class CompositePattern {

    public static void main(String[] args) {
        FileComponent file1 = new ImageFile("图片1");
        FileComponent file2 = new ImageFile("图片2");
        FileComponent folder1 = new Folder("文件夹1");
        FileComponent folder2 = new Folder("文件夹2");

        folder1.add(file1);
        folder2.add(file2);
        folder2.add(folder1);

        System.out.println(folder2.findByName("图片1"));
        System.out.println(folder1.findByName("图片2"));
        System.out.println(folder2.findByName("文件夹1"));
        System.out.println(folder1.findByName("文件夹1"));
    }

    private static abstract class FileComponent {

        protected String name;

        public FileComponent(String name) {
            this.name = name;
        }

        public abstract FileComponent findByName(String fileName);

        public abstract void add(FileComponent file);

        public abstract void remove(FileComponent file);

        public abstract FileComponent getChild(int i);

    }

    private static class ImageFile extends FileComponent {

        public ImageFile(String name) {
            super(name);
        }

        @Override
        public FileComponent findByName(String fileName) {
            return name.equals(fileName) ? this : null;
        }

        @Override
        public void add(FileComponent file) {
            throw new RuntimeException("不支持该操作");
        }

        @Override
        public void remove(FileComponent file) {
            throw new RuntimeException("不支持该操作");
        }

        @Override
        public FileComponent getChild(int i) {
            throw new RuntimeException("不支持该操作");
        }
    }

    private static class Folder extends FileComponent {

        private final List<FileComponent> children = new ArrayList<>();

        public Folder(String name) {
            super(name);
        }

        @Override
        public FileComponent findByName(String fileName) {
            if (name.equals(fileName)) return this;
            for (FileComponent file : children) {
                FileComponent item = file.findByName(fileName);
                if (item != null) return item;
            }
            return null;
        }

        @Override
        public void add(FileComponent file) {
            children.add(file);
        }

        @Override
        public void remove(FileComponent file) {
            children.remove(file);
        }

        @Override
        public FileComponent getChild(int i) {
            return i >= children.size() ? null : children.get(i);
        }
    }

}
